home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 24
/
AACD 24.iso
/
AACD
/
Graphics
/
vpeg
/
vpeg.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-06-10
|
21KB
|
568 lines
/*
** MPEG Hardware Player
**
** by Sigbjørn (CISC) Skjæret
**
**
** Do whatever you want with this code, but I'd appreciate it if you contacted
** me and told me about it first and/or you credited me for it in your project.
**
*/
#define __USE_SYSBASE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/peggympeg.h>
#include "vpeg.h"
#define MAXTOC 100
#define MAXBUF 16384
#define MAXPATH 1024
#define CheckFlag(mask,flag,name) (mask & flag) ? name : ""
static const char Version[] = "$VER: VPeg 2.0 (10.06.01)";
struct IntuitionBase *IntuitionBase = NULL;
struct Library *PeggyMPEGBase;
const ULONG layer[] = { 0, 3, 2, 1 };
const ULONG freq[] = { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000 };
const STRPTR fps[] = { "0", "23.976", "24", "25", "29.97", "30", "50", "59.94", "60" };
const STRPTR aspect[] = { "0:0", "1:1", "1:0.6735", "1:0.7031", "1:0.7615", "1:0.8055", "1:0.8437", "1:0.8935", "1:0.9157 (PAL)", "1:0.9815", "1:1.0255", "1:1.0695", "1:1.0950 (NTSC)", "1:1.1575", "1:1.2015" };
const STRPTR mode[] = { "Stereo", "J-Stereo", "Dual", "Mono" };
const STRPTR track[] = { "Root", "Data", "Audio", "MPEG", "Whitebook", "Unknown" };
ULONG IssueRequest(struct IORequest *Request, ULONG WaitSignals)
{
ULONG signal;
SendIO(Request);
signal = Wait(WaitSignals);
if (signal & ~(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F)) /* Check if any of the signals are non-break ones */
{
while (GetMsg(Request->io_Message.mn_ReplyPort)); /* Empty message-queue */
if (Request->io_Error) /* Check for error */
{
Printf("An error occured while performing command 0x%04lx: %ld.\n", (ULONG)Request->io_Command, (LONG)Request->io_Error);
return NULL;
}
}
return signal;
}
ULONG PeggyCtrl(ULONG signal, ULONG usersig, ULONG ctrlsig, ULONG pegdsig, LONG step, struct IOMPEGReq *PeggyIO, struct IOMPEGReq *Peggy2IO)
{
LONG pause = 0, search = 0;
while (!(signal & usersig))
{
if (signal & SIGBREAKF_CTRL_E)
{
Peggy2IO->iomr_Req.io_Command = MPEGCMD_PAUSE;
Peggy2IO->iomr_StreamType = PeggyIO->iomr_StreamType;
Peggy2IO->iomr_PauseMode = (pause ^= 1);
IssueRequest((struct IORequest *)Peggy2IO, pegdsig);
search = 0;
}
if (signal & SIGBREAKF_CTRL_F)
{
Peggy2IO->iomr_Req.io_Command = MPEGCMD_SEARCH;
Peggy2IO->iomr_StreamType = PeggyIO->iomr_StreamType;
Peggy2IO->iomr_SearchSpeed = (search ^= step);
IssueRequest((struct IORequest *)Peggy2IO, pegdsig);
pause = 0;
}
signal = Wait(usersig | ctrlsig);
while (GetMsg(PeggyIO->iomr_Req.io_Message.mn_ReplyPort));
}
return signal;
}
void PrintStreamInfo(struct MPEGStreamInfo *StreamInfo)
{
switch (StreamInfo->StreamType)
{
case MPEGSTREAM_SYSTEM:
Printf("System Stream -> %lux%lu %lukbps %sfps %s\n", (ULONG)StreamInfo->Width, (ULONG)StreamInfo->Height, (ULONG)StreamInfo->BitRate/1000, fps[StreamInfo->PictureRate], aspect[StreamInfo->AspectRatio]);
break;
case MPEGSTREAM_VIDEO:
Printf("Video Stream -> %lux%lu %lukbps %sfps %s\n", (ULONG)StreamInfo->Width, (ULONG)StreamInfo->Height, (ULONG)StreamInfo->BitRate/1000, fps[StreamInfo->PictureRate], aspect[StreamInfo->AspectRatio]);
break;
case MPEGSTREAM_AUDIO:
Printf("Audio Stream -> Layer%lu %s %luHz %lukbps\n", layer[StreamInfo->AudioLayer], mode[(StreamInfo->AudioMode & MPEGAUD_MODE)>>2], freq[StreamInfo->AudioFreq], (ULONG)StreamInfo->AudioBitRate);
break;
default:
Printf("Unknown streamtype: %lu\n", (ULONG)StreamInfo->StreamType);
break;
}
}
void ClearMPEGReq(struct IOMPEGReq *PeggyIO)
{
PeggyIO->iomr_Req.io_Error = 0;
PeggyIO->iomr_Req.io_Actual = 0;
PeggyIO->iomr_Req.io_Length = 0;
PeggyIO->iomr_Req.io_Data = 0;
PeggyIO->iomr_Req.io_Offset = 0;
PeggyIO->iomr_MPEGError = 0;
PeggyIO->iomr_Version = 0;
PeggyIO->iomr_StreamType = 0;
PeggyIO->iomr_MPEGFlags = 0;
PeggyIO->iomr_Arg1 = 0;
PeggyIO->iomr_Arg2 = 0;
PeggyIO->iomr_PTSHigh = 0;
PeggyIO->iomr_PTSMid = 0;
PeggyIO->iomr_PTSLow = 0;
}
void main(void)
{
APTR mempool = NULL;
BYTE PeggyDevice = -1;
struct RDArgs *rdargs = NULL;
struct Screen *screen = NULL;
struct IOMPEGReq *PeggyIO = NULL;
struct IOMPEGReq *Peggy2IO = NULL;
struct MsgPort *PeggyMP = NULL;
struct MsgPort *Peggy2MP = NULL;
struct PeggyData *Peggy;
STRPTR Template = "FILE/A/M,FINDSYNC/S,NEWSCREEN/S,KEEPSCREEN/S,DISPLAY/K,KEEPAUDIO/S,KEEPVIDEO/S,NOPLAY/S,YCBCRMODE/S,PVC=CONVERTER/S,VOL=VOLUME/N,OP=OPACITY/N,L=LOOPS/N,JL=JUSTIFYLEFT/N,JT=JUSTIFYTOP/N,VCD/S,DEV=DEVICE/K,U=UNIT/N,MPDEV=MPEGDEVICE/K,VERBOSE/S";
enum { TEM_FILE, TEM_FINDSYNC, TEM_NEWSCREEN, TEM_KEEPSCREEN, TEM_DISPLAY, TEM_KEEPAUDIO, TEM_KEEPVIDEO, TEM_NOPLAY, TEM_YCBCR, TEM_CONVERTER, TEM_VOLUME, TEM_OPACITY, TEM_LOOPS, TEM_JUSTIFYLEFT, TEM_JUSTIFYTOP, TEM_VCD, TEM_DEVICE, TEM_UNIT, TEM_MPEGDEV, TEM_VERBOSE, TEM_NUMARGS };
LONG ArgArray[TEM_NUMARGS];
ULONG signal, pegpsig, pegdsig, usersig = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D, ctrlsig = SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F;
STRPTR tempfile = "T:vpeg.tmp";
STRPTR mpegdev = "peggympeg.device";
BPTR fp = NULL;
UWORD loops = 1;
UWORD converter = 0;
UWORD volume = 65535;
UWORD opacity = 65535;
UWORD justleft = 0;
UWORD justtop = 0;
UWORD picrate = MPEG_RATE_AUTO;
ULONG *filearray;
STRPTR filename;
size_t bufsize;
STRPTR buf;
unsigned int pos, i, f, x, offset, cdi = 0;
for (i=0;i<TEM_NUMARGS;ArgArray[i++]=NULL);
if (!(rdargs = ReadArgs(Template,ArgArray,NULL))) { Printf("Invalid arguments.\n"); goto exit; }
if (ArgArray[TEM_VCD] && (!ArgArray[TEM_DEVICE] || !ArgArray[TEM_UNIT])) { Printf("Missing arguments.\n"); goto exit; }
if (!(mempool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, sizeof(struct MPEGCDInfo)*MAXTOC*2, sizeof(struct MPEGCDInfo)*MAXTOC))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (!(Peggy = AllocPooled(mempool, sizeof(struct PeggyData)))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (!(Peggy->DevInfo = AllocPooled(mempool, sizeof(struct MPEGDevInfo)))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (!(Peggy->StreamInfo = AllocPooled(mempool, sizeof(struct MPEGStreamInfo)))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (!(Peggy->Environment = AllocPooled(mempool, sizeof(struct MPEGEnvironment)))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (!(Peggy->AudioParams = AllocPooled(mempool, sizeof(struct MPEGAudioParams)))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (!(Peggy->BorderParams = AllocPooled(mempool, sizeof(struct MPEGBorderParams)))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (!(Peggy->WindowParams = AllocPooled(mempool, sizeof(struct MPEGWindowParams)))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (!(Peggy->VideoParams = AllocPooled(mempool, sizeof(struct MPEGVideoParamsSet)))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
if (ArgArray[TEM_LOOPS]) loops = *((ULONG *)ArgArray[TEM_LOOPS]);
if (ArgArray[TEM_VOLUME]) volume = *((ULONG *)ArgArray[TEM_VOLUME]);
if (ArgArray[TEM_OPACITY]) opacity = *((ULONG *)ArgArray[TEM_OPACITY]);
if (ArgArray[TEM_JUSTIFYLEFT]) justleft = *((ULONG *)ArgArray[TEM_JUSTIFYLEFT]);
if (ArgArray[TEM_JUSTIFYTOP]) justtop = *((ULONG *)ArgArray[TEM_JUSTIFYTOP]);
if (ArgArray[TEM_MPEGDEV]) mpegdev = (STRPTR)ArgArray[TEM_MPEGDEV];
if (ArgArray[TEM_CONVERTER]) converter = 1;
filearray = (ULONG *)ArgArray[TEM_FILE];
if (ArgArray[TEM_DISPLAY])
{
if ((x = strlen((STRPTR)ArgArray[TEM_DISPLAY])) > 0)
{
if (strnicmp((STRPTR)ArgArray[TEM_DISPLAY], "PAL", x) == 0) picrate = MPEG_RATE_PAL;
else if (strnicmp((STRPTR)ArgArray[TEM_DISPLAY], "NTSC", x) == 0) picrate = MPEG_RATE_NTSC;
}
}
if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))) { Printf("Unable to open intuition.library v37+.\n"); goto exit; }
if (!(PeggyMP = CreateMsgPort())) { Printf("Unable to create MsgPort.\n"); goto exit; }
if (!(Peggy2MP = CreateMsgPort())) { Printf("Unable to create MsgPort.\n"); goto exit; }
if (!(PeggyIO = (struct IOMPEGReq *)CreateIORequest(PeggyMP, sizeof(struct IOMPEGReq)))) { Printf("Unable to create IORequest.\n"); goto exit; }
if (!(Peggy2IO = (struct IOMPEGReq *)AllocMem(sizeof(struct IOMPEGReq), MEMF_PUBLIC))) { Printf("Unable to create IORequest.\n"); goto exit; }
if ((PeggyDevice = OpenDevice(mpegdev, 0, (struct IORequest *)PeggyIO, NULL))) { Printf("Unable to open %s.\n", mpegdev); goto exit; }
PeggyMPEGBase = (struct Library *)PeggyIO->iomr_Req.io_Device;
CopyMem(PeggyIO, Peggy2IO, sizeof(struct IOMPEGReq)); /* Duplicate PeggyIO */
Peggy2IO->iomr_Req.io_Message.mn_ReplyPort = Peggy2MP; /* Set up duplicate PeggyIO with alternate MsgPort */
pegpsig = 1L << PeggyMP->mp_SigBit;
pegdsig = 1L << Peggy2MP->mp_SigBit;
if (ArgArray[TEM_VERBOSE])
{
PeggyIO->iomr_Req.io_Command = MPEGCMD_GETDEVINFO;
PeggyIO->iomr_Req.io_Data = Peggy->DevInfo;
PeggyIO->iomr_Req.io_Length = sizeof(struct MPEGDevInfo);
if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
Printf("Board: %s\n",Peggy->DevInfo->mdi_BoardDesc);
Printf("Version: %lu\n",(ULONG)Peggy->DevInfo->mdi_Version);
Printf("Capabilities: %s%s%s%s%s%s%s%s%s\n\n",
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_PLAYRAWVIDEO," RawVideo"),
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_PLAYRAWAUDIO," RawAudio"),
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_PLAYSYSTEM," System"),
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_WINDOWVIDEO," Window"),
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_SCALEVIDEO," Scale"),
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_STEPPLAY," Step"),
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_SCANPLAY," Scan"),
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_SLOWPLAY," Slow"),
CheckFlag(Peggy->DevInfo->mdi_BoardCapabilities,MPEGCF_READFRAME," Read"));
}
if (ArgArray[TEM_NEWSCREEN])
{
ULONG display;
switch (picrate)
{
case MPEG_RATE_NTSC:
display = NTSC_MONITOR_ID;
break;
case MPEG_RATE_PAL:
display = PAL_MONITOR_ID;
break;
default:
if (SysBase->ex_EClockFrequency==715909) display = NTSC_MONITOR_ID;
else display = PAL_MONITOR_ID;
break;
}
screen = OpenScreenTags(NULL, SA_DisplayID, display, SA_ShowTitle, FALSE, SA_Draggable, FALSE, TAG_END);
if (!ArgArray[TEM_KEEPSCREEN])
{
CloseScreen(screen);
screen = NULL;
CloseLibrary((struct Library *)IntuitionBase);
IntuitionBase = NULL;
}
}
if (ArgArray[TEM_FINDSYNC])
{
if (!(buf = (STRPTR)AllocPooled(mempool, MAXBUF))) { Printf("Unable to allocate needed memory.\n"); goto exit; }
}
// /* Init the Peggy+ board */
// PeggyIO->iomr_Req.io_Message.mn_Node.ln_Pri = 0;
// PeggyIO->iomr_Req.io_Command = CMD_RESET;
// if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
/* Video init */
Peggy->VideoParams->mvp_Fade = opacity; /* No effect on Peggy+ (except no video when 0) */
Peggy->VideoParams->mvp_VideoOutput = converter;
Peggy->VideoParams->mvp_DisplayType = picrate;
if (ArgArray[TEM_YCBCR]) Peggy->VideoParams->mvp_ColorMode = YCbCr_MODE;
else Peggy->VideoParams->mvp_ColorMode = RGB_MODE;
PeggyIO->iomr_Req.io_Command = MPEGCMD_SETVIDEOPARAMS;
PeggyIO->iomr_Req.io_Data = Peggy->VideoParams;
PeggyIO->iomr_Req.io_Length = sizeof(struct MPEGVideoParamsSet);
if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
/* Audio init */
Peggy->AudioParams->map_VolumeLeft = volume; /* No effect on Peggy+ (except no audio when 0) */
Peggy->AudioParams->map_VolumeRight = volume;
Peggy->AudioParams->map_AudioMode = MPEG_AUDIO;
// Peggy->AudioParams->map_StreamID = ~0; /* WTF is this for? */
PeggyIO->iomr_Req.io_Command = MPEGCMD_SETAUDIOPARAMS;
PeggyIO->iomr_Req.io_Data = Peggy->AudioParams;
PeggyIO->iomr_Req.io_Length = sizeof(struct MPEGAudioParams);
if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
/* Border init */
Peggy->BorderParams->mbp_BorderLeft = justleft;
Peggy->BorderParams->mbp_BorderTop = justtop;
PeggyIO->iomr_Req.io_Command = MPEGCMD_SETBORDER;
PeggyIO->iomr_Req.io_Data = Peggy->BorderParams;
PeggyIO->iomr_Req.io_Length = sizeof(struct MPEGBorderParams);
if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
// if (ArgArray[TEM_CROP])
// {
// Peggy->WindowParams->mwp_XOffset = 0;
// Peggy->WindowParams->mwp_YOffset = 0;
// Peggy->WindowParams->mwp_Width = 704; /* 352 low-res pixels */
// Peggy->WindowParams->mwp_Height = 288; /* This is Peggy+ max */
// PeggyIO->iomr_Req.io_Command = MPEGCMD_SETWINDOW;
// PeggyIO->iomr_Req.io_Data = Peggy->WindowParams;
// PeggyIO->iomr_Req.io_Length = sizeof(struct MPEGWindowParams);
// if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
// }
if (ArgArray[TEM_VCD])
{
if (!(Peggy->CDInfo = AllocPooled(mempool, sizeof(struct MPEGCDInfo)*MAXTOC))) { Printf("Unable to allocate needed memory.\n"); goto end; }
Peggy->Environment->met_Length = sizeof(struct MPEGEnvironment);
Peggy->Environment->met_Device = (STRPTR)ArgArray[TEM_DEVICE];
Peggy->Environment->met_DevUnit = *((ULONG *)ArgArray[TEM_UNIT]);
Peggy->Environment->met_DevType = MPEGDEV_CDXA;
PeggyIO->iomr_Req.io_Command = MPEGCMD_GETCDCONTENTS;
PeggyIO->iomr_Req.io_Data = Peggy->CDInfo;
PeggyIO->iomr_Req.io_Length = sizeof(struct MPEGCDInfo)*MAXTOC;
PeggyIO->iomr_Arg1 = (LONG)Peggy->Environment;
if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
if (ArgArray[TEM_VERBOSE])
{
Printf("Title: %s\n", Peggy->CDInfo[0].mcd_Name);
Printf("Blocks: %lu\n\n", Peggy->CDInfo[0].mcd_Length);
}
if (Peggy->CDInfo[0].mcd_Length)
for (i=1;Peggy->CDInfo[i].mcd_Length;i++)
{
if (ArgArray[TEM_VERBOSE])
{
Printf("Track %lu: %s\n", (ULONG)Peggy->CDInfo[i].mcd_TrackNumber, Peggy->CDInfo[i].mcd_Name);
Printf("Blocks: %lu-%lu\n", Peggy->CDInfo[i].mcd_StartBlock, Peggy->CDInfo[i].mcd_StartBlock + Peggy->CDInfo[i].mcd_Length);
}
if (Peggy->CDInfo[i].mcd_Length == Peggy->CDInfo[0].mcd_Length)
{
if (!GetCDStreamInfo(Peggy->Environment, Peggy->StreamInfo, 4250, sizeof(struct MPEGStreamInfo)))
{
UWORD Width = Peggy->StreamInfo->Width, Height = Peggy->StreamInfo->Height;
ULONG BitRate = Peggy->StreamInfo->BitRate;
cdi = 4250;
if (ArgArray[TEM_VERBOSE]) Printf("Possible CDi detected, checking for bumper-sequence...\n");
for (f=5300;f<6000;f++)
{
GetCDStreamInfo(Peggy->Environment, Peggy->StreamInfo, f, sizeof(struct MPEGStreamInfo));
if (Peggy->StreamInfo->StreamType == MPEGSTREAM_SYSTEM && Peggy->StreamInfo->Height != 0 && (Peggy->StreamInfo->Height != Height || Peggy->StreamInfo->Width != Width || Peggy->StreamInfo->BitRate != BitRate))
{
cdi = f;
if (ArgArray[TEM_VERBOSE]) Printf("Bumper-sequence detected, skipping to sector %lu!\n", cdi);
break;
}
}
Peggy->CDInfo[i].mcd_TrackType = TRACKTYPE_WHITEMPEG;
Peggy->CDInfo[i].mcd_StartBlock = cdi;
Peggy->CDInfo[i].mcd_Length -= cdi;
}
}
if (Peggy->CDInfo[i].mcd_TrackType == TRACKTYPE_MPEG || Peggy->CDInfo[i].mcd_TrackType == TRACKTYPE_WHITEMPEG)
{
x = GetCDStreamInfo(Peggy->Environment, Peggy->StreamInfo, Peggy->CDInfo[i].mcd_StartBlock, sizeof(struct MPEGStreamInfo));
if (!x)
{
if (ArgArray[TEM_VERBOSE]) PrintStreamInfo(Peggy->StreamInfo);
}
else { if (!cdi) Printf("Couldn't figure out filetype of track %lu.\n", i); continue; }
if (!ArgArray[TEM_NOPLAY])
{
ClearMPEGReq(PeggyIO);
PeggyIO->iomr_Req.io_Command = MPEGCMD_PLAYLSN;
PeggyIO->iomr_Req.io_Data = Peggy->Environment;
PeggyIO->iomr_Req.io_Offset = Peggy->CDInfo[i].mcd_StartBlock;
PeggyIO->iomr_Req.io_Length = Peggy->CDInfo[i].mcd_Length;
PeggyIO->iomr_StreamType = Peggy->StreamInfo->StreamType;
PeggyIO->iomr_SectorSize = 2328; /* The data is really just 2324 */
PeggyIO->iomr_StreamStart = Peggy->CDInfo[i].mcd_StartBlock;
if (loops != 1)
{
PeggyIO->iomr_MPEGFlags = MPEGF_REPEAT;
PeggyIO->iomr_Loops = loops;
}
if (ArgArray[TEM_VERBOSE]) Printf("Playing %s track (CTRL-D to skip / CTRL-C to exit).\n\n", track[Peggy->CDInfo[i].mcd_TrackType]);
if (!(signal = IssueRequest((struct IORequest *)PeggyIO, pegpsig | usersig | ctrlsig))) goto exit;
if (signal & ctrlsig)
{
signal = PeggyCtrl(signal, pegpsig | usersig, ctrlsig, pegdsig, 100, PeggyIO, Peggy2IO);
}
if (signal & usersig)
{
AbortIO((struct IORequest *)PeggyIO);
WaitIO((struct IORequest *)PeggyIO);
SetSignal(0L, pegpsig | usersig); /* Clear signalbits since WaitIO most likely preserves them */
if (signal & SIGBREAKF_CTRL_C) break;
if (signal & SIGBREAKF_CTRL_D) continue;
}
}
}
}
}
else
{
if (!(Peggy->WildAnchor = AllocPooled(mempool, sizeof(struct AnchorPath) + MAXPATH))) { Printf("Unable to allocate needed memory.\n"); goto end; }
Peggy->WildAnchor->ap_Strlen = MAXPATH;
for (f=0,x=0,offset=0;filearray[f];f++)
{
if (!MatchFirst((STRPTR)filearray[f], Peggy->WildAnchor))
{
do
{
filename = Peggy->WildAnchor->ap_Buf;
if (ArgArray[TEM_FINDSYNC])
{
if (!(fp = Open(filename, MODE_OLDFILE))) { Printf("Couldn't open \"%s\".\n", filename); continue; }
for (pos=0;(bufsize=Read(fp, buf, MAXBUF))>0;pos+=bufsize)
{
for (i=0;i<bufsize-4;i++) /* We're lazy, don't overlap buffers */
{
if (buf[i]==0x00 && buf[i+1]==0x00 && buf[i+2]==0x01 && (buf[i+3]==0xBA || buf[i+3]==0xB3))
{
offset = pos+i;
x = 1;
break;
}
}
if (x) break;
if (SetSignal(0,0) & SIGBREAKF_CTRL_C) { MatchEnd(Peggy->WildAnchor); goto end; }
}
Close(fp);
fp = NULL;
}
if (ArgArray[TEM_FINDSYNC] && x)
{
if (ArgArray[TEM_VERBOSE]) Printf("Found sync at %lu\n", offset);
if ((fp = Open(tempfile, MODE_NEWFILE)))
{
Write(fp, &buf[i], bufsize-i);
Close(fp);
fp = NULL;
x = GetStreamInfo(tempfile, Peggy->StreamInfo, sizeof(struct MPEGStreamInfo));
DeleteFile(tempfile);
}
}
else x = GetStreamInfo(filename, Peggy->StreamInfo, sizeof(struct MPEGStreamInfo));
if (!x)
{
if (ArgArray[TEM_VERBOSE]) PrintStreamInfo(Peggy->StreamInfo);
}
else { Printf("Couldn't figure out filetype of, or unable to open \"%s\".\n", filename); continue; }
if (!ArgArray[TEM_NOPLAY])
{
ClearMPEGReq(PeggyIO);
PeggyIO->iomr_Req.io_Command = MPEGCMD_PLAYFILE;
PeggyIO->iomr_Req.io_Data = filename;
PeggyIO->iomr_Req.io_Offset = offset;
PeggyIO->iomr_Req.io_Length = strlen(filename);
PeggyIO->iomr_StreamType = Peggy->StreamInfo->StreamType;
if (loops != 1)
{
PeggyIO->iomr_MPEGFlags = MPEGF_REPEAT;
PeggyIO->iomr_Loops = loops;
}
if (ArgArray[TEM_VERBOSE]) Printf("Playing \"%s\" (CTRL-D to skip / CTRL-C to exit).\n\n", filename);
if (!(signal = IssueRequest((struct IORequest *)PeggyIO, pegpsig | usersig | ctrlsig))) { MatchEnd(Peggy->WildAnchor); goto exit; }
if (signal & ctrlsig)
{
signal = PeggyCtrl(signal, pegpsig | usersig, ctrlsig, pegdsig, 1, PeggyIO, Peggy2IO);
}
if (signal & usersig)
{
AbortIO((struct IORequest *)PeggyIO);
WaitIO((struct IORequest *)PeggyIO);
SetSignal(0L, pegpsig | usersig); /* Clear signalbits since WaitIO most likely preserves them */
if (signal & SIGBREAKF_CTRL_C) { MatchEnd(Peggy->WildAnchor); goto end; }
if (signal & SIGBREAKF_CTRL_D) continue;
}
}
} while (!MatchNext(Peggy->WildAnchor));
MatchEnd(Peggy->WildAnchor);
}
}
}
end:
ClearMPEGReq(PeggyIO);
if (!ArgArray[TEM_KEEPAUDIO])
{
Peggy->AudioParams->map_AudioMode = AMIGA_AUDIO;
PeggyIO->iomr_Req.io_Command = MPEGCMD_SETAUDIOPARAMS;
PeggyIO->iomr_Req.io_Data = Peggy->AudioParams;
PeggyIO->iomr_Req.io_Length = sizeof(struct MPEGAudioParams);
if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
}
if (!ArgArray[TEM_KEEPVIDEO])
{
Peggy->VideoParams->mvp_Fade = 0;
PeggyIO->iomr_Req.io_Command = MPEGCMD_SETVIDEOPARAMS;
PeggyIO->iomr_Req.io_Data = Peggy->VideoParams;
PeggyIO->iomr_Req.io_Length = sizeof(struct MPEGVideoParamsSet);
if (!IssueRequest((struct IORequest *)PeggyIO, pegpsig)) goto exit;
}
exit:
if (fp) Close(fp);
if (rdargs) FreeArgs(rdargs);
if (screen) CloseScreen(screen);
if (!PeggyDevice) CloseDevice((struct IORequest *)PeggyIO);
if (PeggyIO) DeleteIORequest((struct IORequest *)PeggyIO);
if (Peggy2IO) DeleteIORequest((struct IORequest *)Peggy2IO);
if (PeggyMP) DeleteMsgPort(PeggyMP);
if (Peggy2MP) DeleteMsgPort(Peggy2MP);
if (mempool) DeletePool(mempool);
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
}